package com.bbs.lb.other;

import com.bbs.lb.background.*;
import com.bbs.lb.bullet.*;
import com.bbs.lb.music.Music;
import com.bbs.lb.tower.*;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.List;
import java.util.Timer;
import java.util.*;

public class World extends JPanel {

    public static final int WIDTH = 960;//界面宽度
    public static final int HEIGHT = 640;//界面高度
    public static final int STARTGAME = 0;
    public static final int RUNNING = 1;
    public static final int GAMEOVER = 2;
    private static final long serialVersionUID = 1L;
    public static boolean OperateOrNot;
    public static int score = 2000;//初始胡萝卜
    private static BufferedImage[][] image = new BufferedImage[5][2];
    private static BufferedImage updateTower;
    private static BufferedImage deleteTower;
    private static BufferedImage gameover;
    private static BufferedImage[] startgame = new BufferedImage[4];
    private static BufferedImage[] decorateImage = new BufferedImage[7];

    static {
        OperateOrNot = true;
        try {
            for (int i = 0; i < image.length; i++) {
                for (int j = 0; j < image[i].length; j++) {
                    image[i][j] = ImageIO.read(World.class.getResource("/png/select" + i + j + ".png"));//读取炮塔选择图片
                }
            }
            for (int i = 0; i < startgame.length; i++) {
                startgame[i] = ImageIO.read(World.class.getResource("/png/gamestart" + i + ".png"));//读取游戏开始图片
            }
            for (int i = 0; i < decorateImage.length; i++) {
                decorateImage[i] = ImageIO.read(World.class.getResource("/png/decorate" + i + ".png"));//读取装饰物图片
            }
            gameover = ImageIO.read(World.class.getResource("/png/gameover.png"));//读取游戏结束图片
            updateTower = ImageIO.read(World.class.getResource("/png/getPower.png"));//读取炮塔升级图片
            deleteTower = ImageIO.read(World.class.getResource("/png/delete.png"));//读取拆除炮塔图片
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException();
        }
    }

    Music music = new Music();//背景音乐
    private List<AbstractCuteObject> enemies = new ArrayList<AbstractCuteObject>();//怪物
    private BlueBackGround blueDesktop = new BlueBackGround();//背景
    private Path path = new Path();//路径
    private 胡萝卜 carrot = new 胡萝卜();//萝卜
    private GameTools gametools = new GameTools();
    private List<AbstractTowers> towers = Collections.synchronizedList(new ArrayList<AbstractTowers>());//炮塔
    private List<AbstractBullets> bullets = Collections.synchronizedList(new ArrayList<AbstractBullets>());//子弹
    private List<Decorate> decorate = Collections.synchronizedList(new ArrayList<Decorate>());//装饰物
    private int gameState = 0;//游戏状态，0开始，1游戏中，2游戏结束
    //生成怪物的方法
    private int wait = 300;
    private int index = 0;
    private boolean EnterSwitch = false;
    private int waveCount = 0;//第几波
    private boolean SELECT_TOWER = false;//要搭建新炮塔时为true
    private boolean updateTowerOrNot = false;//是否升级炮塔
    private boolean deleteTowerOrNot = false;//是否拆除炮塔
    private AbstractTowers choseTower = null;//被选中的炮塔
    private int selectTowerX;//新建炮塔时的坐标
    private int selectTowerY;

    public void getMonster() {
        /*
         * 该方法生成新的怪物（wait自增控制怪物之间的间隔，当wait%335==0为true时开始生成怪物，每当生成40个之后停
         * 由ENEMYNUM决定波有多少个
         */
        if (!EnterSwitch) {
            wait++;
            if (wait % 100 == 0) {
                EnterSwitch = true;
                Enemy.HPs += 5;
            }
        }
        if (EnterSwitch) {
            if (index++ % 7 == 0) {
                AbstractCuteObject cute = new Enemy();
                enemies.add(cute);
                waveCount = Enemy.waveCount;
                if (Enemy.EnemyIndex % Enemy.ENEMY_NUM == Enemy.ENEMY_NUM - 1) {
                    EnterSwitch = false;
                }
            }
        }

    }

    //使怪物移动
    public void enableEnemy() {
        for (AbstractCuteObject obj : enemies) {
            obj.move();
            gametools.turn(obj);
        }
    }

    //移除越界元素：怪物吃萝卜和子弹出界
    public void dropEnemeis() {

        Iterator<AbstractCuteObject> it = enemies.iterator();
        while (it.hasNext()) {
            AbstractCuteObject enemy = it.next();
            if ((enemy.getX() < path.SPECIAL_POINT[8][0] + 10 && enemy.getX() > path.SPECIAL_POINT[8][0] - 10)
                    &&
                    (enemy.getY() < path.SPECIAL_POINT[8][1] + 10 && enemy.getY() > path.SPECIAL_POINT[8][1] - 10)) {
                //怪到萝卜附近
                carrot.setHP(carrot.getHP() - 1);//萝卜掉血
                it.remove();//移除怪物
            }
        }

        Iterator<AbstractBullets> it2 = bullets.iterator();
        while (it2.hasNext()) {
            AbstractBullets bullet = it2.next();
            if ((bullet.getX() <= 0 - bullet.width || bullet.getX() >= WIDTH + bullet.width)
                    ||
                    (bullet.getY() <= 0 - bullet.height || bullet.getY() >= HEIGHT + bullet.height)) {
                //子弹出界，移除子弹
                it2.remove();
            }
        }
    }

    //启动炮塔，攻击范围内的怪物
    public void startTower() {
        int i = 0;
        if (enemies.size() == 0) {
            //没有怪物
            for (AbstractTowers t : towers) {
                t.setShootState(false);//炮塔为不发射状态
            }
            return;
        } else if (enemies.size() != 0) {
            //有怪物
            for (AbstractTowers t : towers) {
                for (; i < enemies.size(); ) {
                    Enemy enemy = (Enemy) enemies.get(i);
                    if (gametools.canShoot(enemy, t)) {
                        //进入射程
                        t.setShootState(true);//炮塔置为发射状态
                        t.setTowerAngle(gametools.getAngle(enemy, t));//获取角度并置为炮塔角度
                        break;//结束对怪物的遍历，判断下一炮塔
                    } else {
                        //不在射程内
                        t.setShootState(false);//炮塔置为不发射状态
                        if (i == enemies.size() - 1) {
                            //对怪物的遍历结束，判断下一炮塔
                            break;
                        }
                        i++;
                    }
                }
            }
        }
    }

    //管理子弹
    public void manageBullets() {
        try {
            List<AbstractBullets> list = new ArrayList<AbstractBullets>();
            for (AbstractTowers t : towers) {
                AbstractBullets buttle = t.getNewBullet();
                if (buttle != null) {
                    list.add(buttle);
                }
            }
            bullets.addAll(list);

            //除风扇头子弹外，其他子弹若超出对应射程，即没有打到怪物的，移除该子弹
            //只有风扇头子弹可以连续击打多名怪物
            bullets.removeIf(buttle -> buttle.isOutOfDistance() && !(buttle instanceof BulletOfFan));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //子弹命中怪物后的效果
    public void isBangAction() {
        List<Decorate> decorteList = new ArrayList<Decorate>();
        List<AbstractBullets> bulletList = new ArrayList<AbstractBullets>();
        List<Enemy> deathList = new ArrayList<Enemy>();
        Iterator<AbstractBullets> itBullet = bullets.iterator();

        while (itBullet.hasNext()) {
            //遍历子弹
            AbstractBullets buttle = itBullet.next();

            Iterator<AbstractCuteObject> itEnemy = enemies.iterator();
            while (itEnemy.hasNext()) {
                //遍历怪物
                Enemy enemy = (Enemy) itEnemy.next();
                if (enemy.getHP() <= 0) {
                    //每当怪物被击杀，得4胡萝卜
                    deathList.add(enemy);
                    score += 4;
                }

                if (gametools.bangAction(enemy, buttle)) {
                    //子弹命中怪物
                    if (buttle instanceof BulletOfGreen) {    //普通绿头子弹
                        decorteList.add(new Decorate(buttle.getX(), buttle.getY(), 0));        //命中效果
                        bulletList.add(buttle);
                    } else if (buttle instanceof BulletOfStar) {    //星头子弹、群伤
                        BulletOfStar st = (BulletOfStar) buttle;
                        if (st.isBoom()) {
                            decorteList.add(new Decorate(buttle.getX(), buttle.getY() + 50, 3));
                            bulletList.add(buttle);
                        } else {
                            //子弹变大造成群伤效果
                            st.setBoom(true);
                            st.setX(st.getX() - 120);
                            st.setY(st.getY() - 120);
                            st.setWidth(st.getWidth() + 120);
                            st.setHeight(st.getHeight() + 120);
                        }
                    } else if (buttle instanceof BulletOfFan) {    //风扇头子弹
                        decorteList.add(new Decorate(buttle.getX(), buttle.getY(), 1));
                    } else if (buttle instanceof BulletOfCuttle) {    //章鱼头子弹
                        decorteList.add(new Decorate(buttle.getX(), buttle.getY(), 2));
                        bulletList.add(buttle);
                    } else if (buttle instanceof BulletOfBlueStar) {    //蓝星头子弹，冷冻效果、群伤
                        BulletOfBlueStar st = (BulletOfBlueStar) buttle;
                        if (st.isBoom()) {
                            if (!enemy.isCold()) {
                                enemy.setSpeed(enemy.getSpeed() - (buttle.getLevel() + 1) * 4);//冷冻降速
                            }
                            enemy.setCold(true);
                            decorteList.add(new Decorate(buttle.getX(), buttle.getY() + 50, 4));
                            bulletList.add(buttle);
                        } else {
                            st.setBoom(true);
                            st.setX(st.getX() - 120);
                            st.setY(st.getY() - 120);
                            st.setWidth(st.getWidth() + 120);
                            st.setHeight(st.getHeight() + 120);
                        }
                    }
                    enemy.setHP(enemy.getHP() - buttle.getAtk());//子弹命中怪物，怪物掉血
                }

            }
        }

        decorate.addAll(decorteList);
        bullets.removeAll(bulletList);
        enemies.removeAll(deathList);
    }

    public void action() {
        music.play();//播放背景音乐
        MouseAdapter l = new MouseAdapter() {
            int x;
            int y;

            public void mouseMoved(MouseEvent e) {
                //监听鼠标的x坐标和y坐标
                x = e.getX();
                y = e.getY();
            }

            public void mouseClicked(MouseEvent e) {
                if (gameState == STARTGAME) {
                    gameState = RUNNING;
                } else if (gameState == RUNNING) {
                    if (gametools.canOperate(x, y)) {
                        //鼠标在合法范围内点击
                        if (SELECT_TOWER == false && updateTowerOrNot == false && deleteTowerOrNot == false) {

                            if ((choseTower = gametools.hasTower(towers, x, y)) != null) {
                                //点击区域已有炮塔，则可调出拆除和升级
                                deleteTowerOrNot = true;//炮塔可拆除
                                OperateOrNot = false;
                                if (score < choseTower.getPayFor() || choseTower.getLevel() == 2) {
                                    updateTowerOrNot = false;//炮塔不可升级
                                } else {
                                    updateTowerOrNot = true;//炮塔可升级
                                }

                            } else {
                                //无炮塔，则可搭建新炮塔
                                selectTowerX = x;
                                selectTowerY = y;
                                SELECT_TOWER = true;
                                OperateOrNot = false;
                                //选择炮塔后,不再判断是否可以进行Operate,任何坐标都可以通过第一层if
                            }
                        } else {
                            if (SELECT_TOWER) {
                                //新建炮塔
                                if ((x > selectTowerX - 25 && x < selectTowerX + 25) && (y > selectTowerY + 10 && y < selectTowerY + 50) && score >= 100) {
                                    //选择搭建绿头炮塔
                                    towers.add(new GreenTower((selectTowerX / 52) * 52, (selectTowerY / 52) * 52));
                                    score -= 100;
                                }
                                if ((x > selectTowerX + 25 && x < selectTowerX + 75) && (y > selectTowerY + 10 && y < selectTowerY + 50) && score >= 160) {
                                    //选择搭建风扇头炮塔
                                    towers.add(new FanTower((selectTowerX / 52) * 52, (selectTowerY / 52) * 52));
                                    score -= 160;
                                }
                                if ((x > selectTowerX + 75 && x < selectTowerX + 125) && (y > selectTowerY + 10 && y < selectTowerY + 50) && score >= 160) {
                                    //选择搭建章鱼头炮塔
                                    towers.add(new CuttleTower((selectTowerX / 52) * 52, (selectTowerY / 52) * 52));
                                    score -= 220;
                                }
                                if ((x > selectTowerX - 75 && x < selectTowerX - 25) && (y > selectTowerY + 10 && y < selectTowerY + 50) && score >= 160) {
                                    //选择搭建星头炮塔
                                    towers.add(new StarTower((selectTowerX / 52) * 52, (selectTowerY / 52) * 52));
                                    score -= 160;
                                }
                                if ((x > selectTowerX - 125 && x < selectTowerX - 75) && (y > selectTowerY + 10 && y < selectTowerY + 50) && score >= 160) {
                                    //选择搭建蓝星头炮塔
                                    towers.add(new BlueStarTower((selectTowerX / 52) * 52, (selectTowerY / 52) * 52));
                                    score -= 180;
                                }
                                SELECT_TOWER = false;
                            }
                            if (choseTower != null) {
                                //判断选择升级还是拆除炮塔
                                if (updateTowerOrNot && (x > choseTower.getX() - 5 && x < choseTower.getX() + 70) && (y <= choseTower.getY() + 10 && y >= choseTower.getY() - 70)) {
                                    //升级炮塔
                                    if (choseTower.getLevel() < 2) {
                                        choseTower.setLevel(choseTower.getLevel() + 1);
                                    }
                                }
                                if (deleteTowerOrNot && (x > choseTower.getX() - 5 && x < choseTower.getX() + 60) && (y <= choseTower.getY() + 110 && y >= choseTower.getY() + 50)) {
                                    //拆除炮塔
                                    score += (int) (choseTower.getPayFor() * 0.7 * (choseTower.getLevel() + 1));
                                    towers.remove(choseTower);
                                }
                                updateTowerOrNot = false;
                                deleteTowerOrNot = false;
                                choseTower = null;
                            }
                        }
                    }
                }
            }
        };
        this.addMouseListener(l);
        this.addMouseMotionListener(l);

        //安排任务在特定时间内重复执行
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            public void run() {
                if (gameState == RUNNING) {
                    getMonster();
                    enableEnemy();
                    startTower();
                    dropEnemeis();
                    manageBullets();
                    isBangAction();
                }
                repaint();
            }
        }, 65, 65);
    }

    //画出选择防御塔的图片
    public void paintSelectTowerImage(Graphics g) {

        if (SELECT_TOWER) {
            int index = 0;
            if (score >= 100) {
                index = 1;
            } else {
                index = 0;
            }
            g.drawImage(image[0][index], selectTowerX - 25, selectTowerY + 10, null);
            if (score >= 160) {
                index = 1;
            } else {
                index = 0;
            }
            g.drawImage(image[1][index], selectTowerX + 25, selectTowerY + 10, null);
            if (score >= 220) {
                index = 1;
            } else {
                index = 0;
            }
            g.drawImage(image[2][index], selectTowerX + 75, selectTowerY + 10, null);
            if (score >= 160) {
                index = 1;
            } else {
                index = 0;
            }
            g.drawImage(image[3][index], selectTowerX - 75, selectTowerY + 10, null);
            if (score >= 180) {
                index = 1;
            } else {
                index = 0;
            }
            g.drawImage(image[4][index], selectTowerX - 125, selectTowerY + 10, null);

        }
        //升级防御塔图片
        if (choseTower != null && updateTowerOrNot) {
            g.drawImage(updateTower, choseTower.getX() + 5, choseTower.getY() - 45, null);

        }
        if (choseTower != null && deleteTowerOrNot) {
            g.drawImage(deleteTower, choseTower.getX() + 8, choseTower.getY() + 60, null);
        }
    }

    //画装饰物
    public void paintSomeDecorate(Graphics g) {
        g.drawImage(decorateImage[4], 384, 254, null);
        g.drawImage(decorateImage[4], 454, 254, null);
        g.drawImage(decorateImage[4], 524, 254, null);
        g.drawImage(decorateImage[6], 314, 254, null);
        g.drawImage(decorateImage[6], 594, 254, null);
        g.drawImage(decorateImage[0], 428, 110, null);
        g.drawImage(decorateImage[1], 298, 125, null);
        g.drawImage(decorateImage[1], 558, 125, null);
        g.drawImage(decorateImage[2], 205, 160, null);
        g.drawImage(decorateImage[2], 713, 160, null);
        g.drawImage(decorateImage[3], 200, 440, null);
        g.drawImage(decorateImage[3], 656, 440, null);
    }

    public void paint(Graphics g) {
        if (gameState == GAMEOVER) {
            g.drawImage(gameover, 105, 80, null);
            return;
        }
        if (gameState == STARTGAME) {
            g.drawImage(startgame[0], 0, 0, null);
            g.drawImage(startgame[1], 0, 0, null);
            g.drawImage(startgame[2], 330, 400, null);
            g.drawImage(startgame[3], 0, 0, null);
            return;
        }

        blueDesktop.paint(g);
        paintSomeDecorate(g);
        path.paint(g);
        carrot.paint(g);

        Iterator<AbstractCuteObject> it4 = enemies.iterator();
        while (it4.hasNext()) {
            AbstractCuteObject obj = it4.next();
            obj.paint(g);
        }

        g.drawImage(decorateImage[5], 320, 380, null);
        g.drawImage(decorateImage[5], 550, 380, null);

        Iterator<Decorate> it3 = decorate.iterator();
        while (it3.hasNext()) {
            Decorate d = it3.next();
            d.paint(g);
            if (d.getIndex() == 5) {
                it3.remove();
            }
        }

        Iterator<AbstractTowers> it = towers.iterator();
        while (it.hasNext()) {
            AbstractTowers ts = it.next();
            ts.turnTowers(g);
        }

        Iterator<AbstractBullets> it2 = bullets.iterator();
        while (it2.hasNext()) {
            AbstractBullets b = it2.next();
            b.paint(g);
            System.out.println(b.getAtk());
        }

        paintSelectTowerImage(g);
        Font f = new Font(Font.DIALOG, Font.BOLD, 20);
        g.setFont(f);
        g.setColor(Color.ORANGE);
        g.drawString("胡萝卜:" + score, 420, 25);
        g.drawString("波次:" + waveCount, 420, 60);
        g.drawString("生命值:" + carrot.getHP(), 800, 25);
        if (carrot.getHP() <= 0) {
            gameState = GAMEOVER;
        }

    }

}
